package pkg

import (
	"fmt"
	"net"
	"strings"
)

type User struct {
	Name string
	Addr string
	//channel 消费内容是 string
	C chan string
	//user 对应的 conn，接收消息内容
	conn net.Conn
	//绑定server
	server *Server
}

/*
*
param conn
return user
*/
func NewUser(conn net.Conn, server *Server) *User {
	userAddr := conn.RemoteAddr().String()
	user := &User{
		Addr: userAddr,
		Name: userAddr,
		//通过该channel向user发消息
		C:      make(chan string),
		conn:   conn,
		server: server,
	}

	//开启协程，监听当前user的channel
	go user.listenMsg()

	fmt.Printf("\n 新用户上线了，地址：" + userAddr)
	return user
}

// 用户上线业务
func (u *User) Online() {
	u.server.mapLock.Lock()
	//用户上线
	u.server.OnlineUserMap[u.Name] = u
	u.server.mapLock.Unlock()

	//广播上线
	u.server.BroadCast(u, "上线")
}

// 用户下线业务
func (u *User) Offline() {
	//将user从onlineMap中删除
	u.server.mapLock.Lock()
	delete(u.server.OnlineUserMap, u.Name)
	u.server.mapLock.Unlock()

	//广播下线
	u.server.BroadCast(u, "下线")
}

// 处理用户客户端发来的消息
func (u *User) DoMessage(msg string) {
	//查询在线用户
	if msg == "who" {
		u.server.mapLock.Lock()
		//遍历onlineUserMap，并返回结果到user控制台
		for _, user := range u.server.OnlineUserMap {
			onlineMsg := "[" + user.Addr + "]" + user.Name + ":" + "在线\n"
			u.sendMsg(onlineMsg)
		}
		u.server.mapLock.Unlock()
	} else if msg[:7] == "rename|" {
		newName := strings.Split(msg, "|")[1]
		//判断name是否存在
		_, ok := u.server.OnlineUserMap[newName]
		if ok {
			u.sendMsg("当前用户名已经被使用\n")
		} else {
			u.server.mapLock.Lock()
			delete(u.server.OnlineUserMap, u.Name)
			u.server.OnlineUserMap[newName] = u
			u.server.mapLock.Unlock()

			u.Name = newName
			fmt.Printf("您已经更改用户名：" + newName + "\n")
			u.sendMsg("您已经更改用户名：" + newName + "\n")
		}
	} else {
		u.server.BroadCast(u, msg)
	}
}

/*
监听当前 user 的 channel，将 msg 发给 conn
*/
func (u *User) listenMsg() {
	for {
		//从 user 的 channel 读取 msg
		msg := <-u.C
		fmt.Printf("\n 当前用户" + u.Name + "收到了广播消息,消息内容是:" + msg)
		//向 conn 写入 msg，客户端控制台可以看到内容
		u.conn.Write([]byte(msg + "\n"))
	}
}

// 向user对应的客户端发送消息
func (u *User) sendMsg(msg string) {
	u.conn.Write([]byte(msg))
}
